﻿Imports System.Collections.ObjectModel
Imports System.ComponentModel

Public MustInherit Class TokenBaseVm
    Inherits ViewModelBase

    Private mUsage As TokenUsage
    Public ReadOnly Property Usage As TokenUsage
        Get
            Return mUsage
        End Get
    End Property

    Public Sub New(token As Token, objectVm As RawObjectVm, usage As TokenUsage)
        mToken = token
        mUsage = usage
        mObjectVm = objectVm
    End Sub

    Protected Overridable Function GenerateArguments() As List(Of ArgumentBaseVm)
        Dim vms As New List(Of ArgumentBaseVm)
        Dim argIndex As Integer = 0

        Dim handler As IArgsTypeHandler = Usage.GetArgsHandler
        Do While argIndex < Token.Arguments.Count
            Dim def As ArgumentDefinition = handler.GetArgument(argIndex, Usage)

            Dim vm As ArgumentBaseVm = ArgVmManager.Instance.GetArgVmFor(def)
            vm.Init(Me, ObjectVm, def, Token.Arguments(argIndex))

            vms.Add(vm)
            argIndex += 1
        Loop

        Return vms
    End Function

    Private mObjectVm As RawObjectVm
    Public ReadOnly Property ObjectVm As RawObjectVm
        Get
            Return mObjectVm
        End Get
    End Property

    Private mToken As Token
    Public ReadOnly Property Token As Token
        Get
            Return mToken
        End Get
    End Property

    Public ReadOnly Property Name As String
        Get
            Return mToken.Name
        End Get
    End Property

    Public ReadOnly Property ArgumentsAsString As String
        Get
            Return mToken.ArgumentsAsString
        End Get
        'Set(value As String)
        '    mToken.ReparseArgs(value, mObjectVm.RawObject)
        '    mArguments = Nothing
        '    RaisePropertyChanged("Arguments")
        '    RaisePropertyChanged("ArgumentsAsString")
        'End Set
    End Property

    Dim mArguments As BindingList(Of ArgumentBaseVm)
    Public ReadOnly Property Arguments As BindingList(Of ArgumentBaseVm)
        Get
            If mArguments Is Nothing Then
                If mUsage IsNot Nothing Then
                    mArguments = New BindingList(Of ArgumentBaseVm)
                    mArguments.AllowNew = True
                    AddHandler mArguments.AddingNew, Sub(sender As Object, e As AddingNewEventArgs)
                                                         Dim handler As IArgsTypeHandler = Usage.GetArgsHandler
                                                         Dim vm As StringArgVm = New StringArgVm()
                                                         vm.Init(Me, ObjectVm, handler.GetArgument(mArguments.Count, Usage), "")
                                                         e.NewObject = vm
                                                     End Sub
                    For Each arg As ArgumentBaseVm In GenerateArguments()
                        mArguments.Add(arg)
                    Next
                    RaisePropertyChanged("Arguments")
                End If
            End If
            Return mArguments
        End Get
    End Property

    Public Sub RefreshArguments()
        For i As Integer = 0 To Arguments.Count - 1
            Dim arg As ArgumentBaseVm = Arguments(i)
            arg.Value = Me.Token.GetArgumentOrDefault(i, "")
        Next
    End Sub

    Public MustOverride ReadOnly Property CanAddArguments As Boolean


    Private mIsSelected As Boolean
    Public Property IsSelected As Boolean
        Get
            Return mIsSelected
        End Get
        Set(value As Boolean)
            If value <> mIsSelected Then
                mIsSelected = value
                RaisePropertyChanged("IsSelected")
                RaisePropertyChanged("ShouldShowDetails")
            End If
        End Set
    End Property

    Public ReadOnly Property CanShowDetails As Boolean
        Get
            Return mToken.Arguments.Count > 0 OrElse CanAddArguments
        End Get
    End Property

    Public Sub SetArgumentValue(index As Integer, value As String)
        If index < mToken.Arguments.Count Then
            mToken.Arguments(index) = value
        Else
            mToken.Arguments.Add(value)
        End If
        RaisePropertyChanged("ArgumentsAsString")
    End Sub
End Class
